package com.blueocean_health.care.management.service.impl;

import com.blueocean_health.care.management.common.base.pinyin.Chinese2PinyinUtils;
import com.blueocean_health.care.management.common.base.string.StringUtils;
import com.blueocean_health.care.management.domain.base.*;
import com.blueocean_health.care.management.domain.dto.NurseGroupDto;
import com.blueocean_health.care.management.em.GroupDeflagEnum;
import com.blueocean_health.care.management.em.GroupLeaderEnum;
import com.blueocean_health.care.management.exception.OrderException;
import com.blueocean_health.care.management.mapper.NurseCheckWorkMapper;
import com.blueocean_health.care.management.mapper.NurseGroupMapper;
import com.blueocean_health.care.management.mapper.NurseGroupRelationMapper;
import com.blueocean_health.care.management.mapper.OrderServiceNurseInfoMapper;
import com.blueocean_health.care.management.service.NurseGroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Author ChenPeng cp
 * @Date 2018/1/3 15:40
 */

@Service
public class NurseGroupServiceImpl implements NurseGroupService{

    @Autowired
    private NurseGroupMapper nurseGroupMapper;

    @Autowired
    private NurseGroupRelationMapper nurseGroupRelationMapper;

    @Autowired
    private OrderServiceNurseInfoMapper orderServiceNurseInfoMapper;

    @Autowired
    private NurseCheckWorkMapper nurseCheckWorkMapper;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public SysResult addNurseGroup(NurseGroupDto nurseGroupDto) throws OrderException {

        //校验提成比例是否在规定范围 0≤数值≤100
        if (StringUtils.isEmpty(nurseGroupDto.getProportions())){
            return SysResult.error("提成比例不可为空");
        }
        Boolean proFlag =  0 <= nurseGroupDto.getProportions() || nurseGroupDto.getProportions() <= 100;
        if (!proFlag){
            return SysResult.error("请输入正确范围的提成比例：0≤数值≤100 ");
        }

        //判断是新增还是编辑  true:新增  false:编辑
        Boolean updateFlag = true;
        if (!StringUtils.isEmpty(nurseGroupDto.getGroupId())){
            updateFlag = false;
        }
        //若无保底薪资 保底薪资传 0  2018年5月24日16:43:44
//        if(!StringUtils.isEmpty(nurseGroupDto.getHavePayroll())){
//        	if("0".equals(nurseGroupDto.getHavePayroll())){
//        		nurseGroupDto.setPayroll(0d);
//        	}
//        }
        //校验小组名是否存在，不可重复
        String groupName = nurseGroupDto.getGroupName().replaceAll(" ","");
        if(StringUtils.isEmpty(groupName)){
            return SysResult.error("小组名称不可以为空");
        }

        //编辑时数据库中肯定会有一个，新增时不会有
        NurseGroup nurseGroupByName = nurseGroupMapper.getNurseGroupByName(groupName,nurseGroupDto.getHospitalId());
        if (nurseGroupByName != null){
            if (updateFlag){
                return SysResult.error("该小组已存在，请勿重复提交");
            }else {
                //编辑时，校验库中有的那个是不是当前编辑的，不是的话驳回
                if (!nurseGroupByName.getGroupId().equals(nurseGroupDto.getGroupId())){
                    return SysResult.error("该小组已存在，请勿重复提交");
                }
            }
        }

        //校验小组最少有一个成员
        List<NurseGroupRelation> nurseList = nurseGroupDto.getNurseList();
        if (nurseList.size() < 1){
            return SysResult.error("请至少添加一位小组成员");
        }

        //校验小组成员内是否最少有一个组长
        long leaderCount = nurseList.stream().filter(info -> GroupLeaderEnum._1.getKey().equals(info.getLeaderFlag())).count();
        if (leaderCount < 1){
            return SysResult.error("请至少添加一位小组组长");
        }

        //校验小组成员是否重复
        List<String> nurseIds = new ArrayList<>();
        nurseList.forEach(info -> nurseIds.add(info.getNurseId()));
        Set set = new HashSet();
        set.addAll(nurseIds);
        if (set.size() != nurseIds.size()){
            return SysResult.error("同一个护工只能选择一次");
        }

        //校验小组成员是否在其他组存在
        //先查出最高版本的所有未删除小组的护工，得到idlist，然后比较入参的id，包含的话就代表有冲突
        List<NurseGroupRelation> infoByHospitalId = nurseGroupRelationMapper.getAllMaxInfoByHospitalId(nurseGroupDto.getHospitalId());
        List<String> maxVersionNurseIds = new ArrayList<>();
        if (updateFlag){
            infoByHospitalId.forEach(info -> maxVersionNurseIds.add(info.getNurseId()));
        }else {
            //编辑时，排除之前本组的成员，得到其他组最高版本的所有护工，进行比较
            infoByHospitalId
                    .stream()
                    .filter(info -> !nurseGroupDto.getGroupId().equals(info.getGroupId()))
                    .forEach(info -> maxVersionNurseIds.add(info.getNurseId()));
        }
        //通过set的去重特性，把入参的ids 和 查到的ids放到一起，判断长度是否改变
        maxVersionNurseIds.forEach(s -> set.add(s));
        if (set.size() != (nurseIds.size() + maxVersionNurseIds.size())){
            return SysResult.error("一个护工只能同时存在于一个小组中");
        }

        //添加or编辑小组
        Date now = new Date();
        
        NurseGroup nurseGroup = new NurseGroup();
        //新增字段  2018年5月14日14:47:59
        nurseGroup.setNurseFeeType(nurseGroupDto.getNurseFeeType());
        nurseGroup.setHavePayroll(nurseGroupDto.getHavePayroll());
//        nurseGroup.setPayroll(nurseGroupDto.getPayroll());
        
        nurseGroup.setGroupName(nurseGroupDto.getGroupName());
        nurseGroup.setDeflag(GroupDeflagEnum._0.getKey());
        nurseGroup.setHospitalId(nurseGroupDto.getHospitalId());
        nurseGroup.setProportions(nurseGroupDto.getProportions());
        nurseGroup.setUpdateTime(now);
        String pinyinAll = Chinese2PinyinUtils.toPinyinAll(nurseGroupDto.getGroupName());
        nurseGroup.setGroupNamePy(pinyinAll);

        int dbFlag = 0;
        if (updateFlag){
            nurseGroup.setCreateTime(now);
            nurseGroupMapper.add(nurseGroup);
            //获取insert之后返回的主键
            dbFlag = nurseGroup.getGroupId();
        }else {
            nurseGroup.setGroupId(nurseGroupDto.getGroupId());
            NurseGroup byPrimaryKey = nurseGroupMapper.selectByPrimaryKey(nurseGroup);
            nurseGroup.setCreateTime(byPrimaryKey.getCreateTime());
            dbFlag = nurseGroupMapper.updateByPrimaryKey(nurseGroup);
        }

        if (dbFlag < 1){
            throw new  OrderException("小组信息保存失败");
        }

        //获取小组id
        Integer groupId = null;
        if (updateFlag){
            groupId = dbFlag;
        }else {
            groupId = nurseGroupDto.getGroupId();
        }

        //增量添加关联护工中间表
        for (NurseGroupRelation relation:nurseList) {
            NurseGroupRelation dbinfo = new NurseGroupRelation();
            dbinfo.setLeaderFlag(relation.getLeaderFlag());
            dbinfo.setNurseId(relation.getNurseId());
            dbinfo.setGroupId(groupId);
            dbinfo.setVersion(nurseGroupDto.getVersion());
            dbinfo.setUpdateTime(now);
            dbinfo.setDeflag(0);
            dbFlag =  nurseGroupRelationMapper.insert(dbinfo);
            if (dbFlag < 1){
                throw new OrderException("小组成员信息保存失败");
            }
        }

        return SysResult.ok();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public SysResult updateNurseGroupDeflag(Integer groupId, String groupDeflag)  throws OrderException{
        if (StringUtils.isEmpty(groupId)){
            return SysResult.error("小组id为空");
        }
        //校验该小组名下有没有订单
        Set set = new HashSet();
        List<OrderServiceNurseInfo> allMaxVersionGroupOrder = orderServiceNurseInfoMapper.getAllMaxVersionGroupOrder();
        allMaxVersionGroupOrder.forEach(info -> set.add(info.getWorkerId()));

        int groupOrderSize = set.size();

        set.add(groupId+"");

        if (set.size() == groupOrderSize){
            return SysResult.error("该小组目前有关联订单，暂时不可删除");
        }

        //校验该小组有没有考勤记录
        List<NurseCheckWork> nurseCheckWorks = nurseCheckWorkMapper.queryAllByGroupId(groupId);
        if (nurseCheckWorks.size() > 0){
            return SysResult.error("该小组目前有关联考勤记录，暂时不可删除");
        }

        int dbFlag =  nurseGroupMapper.updateNurseGroupDeflagByGroupId(groupId,groupDeflag);

        if (dbFlag < 1){
            return SysResult.error("删除小组失败");
        }else {
            //删除护工小组关联表
            dbFlag = nurseGroupRelationMapper.updateNurseGroupRelationDeflagByGroupId(groupId);
            if (dbFlag < 1){
                throw new OrderException("删除小组失败");
            }
        }
        return SysResult.ok();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int updateNurseGroupRelationDeflag(String nurseId) throws OrderException{
        if (StringUtils.isEmpty(nurseId)){
            throw new OrderException("nurseId不可为空");
        }
        return nurseGroupRelationMapper.updateNurseGroupRelationDeflag(nurseId);
    }


}
